package com.dhp.mq;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.dhp.Utils.AIUtil;
import com.dhp.Utils.WebSocketUtil;
import com.dhp.common.ErrorCode;
import com.dhp.constant.GenChartConstant;
import com.dhp.constant.MQConstant;
import com.dhp.constant.UserConstant;
import com.dhp.exception.BusinessException;
import com.dhp.model.entity.Chart;
import com.dhp.model.entity.ChartData;
import com.dhp.model.enums.GenChartStatusEnum;
import com.dhp.service.ChartDataService;
import com.dhp.service.ChartService;
import com.google.gson.Gson;
import com.rabbitmq.client.Channel;
import org.apache.commons.lang3.StringUtils;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.amqp.support.AmqpHeaders;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.messaging.handler.annotation.Header;
import org.springframework.stereotype.Component;

import java.io.IOException;
import java.util.List;

@Component
public class DeadMessageCommonConsumer {



    @Autowired
    private
    ChartService chartService;

    @Autowired
    private AIUtil aiUtil;

    @Autowired
    private ChartDataService chartDataService;

    @Autowired
    private StringRedisTemplate redisTemplate;

    @Autowired
    private WebSocketUtil webSocketUtil;


    /**
     * 死信消费者，将生成失败的图标状态改为failed
     * @param message
     * @param channel
     * @param deliveryTag
     */
    @RabbitListener(queues = {MQConstant.COMMON_DEAD_QUEUE} , ackMode = "MANUAL")
    public void receiveMessage(String message , Channel channel , @Header(AmqpHeaders.DELIVERY_TAG) long deliveryTag) {

        if (StrUtil.isEmpty(message)) {
            //message为空则丢弃消息
            try {
                channel.basicAck(deliveryTag, false);
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        }

        //执行核心逻辑
        Long chartId = Long.parseLong(message);
        //获取AI完整的回答
        Chart RunningChart = chartService.getById(chartId);
        //根据charId查询data
        QueryWrapper<ChartData> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("chartId" , RunningChart.getId());
        ChartData data = chartDataService.getOne(queryWrapper);
        if (data == null){

            try {
                channel.basicAck(deliveryTag, false);
                throw new BusinessException(ErrorCode.OPERATION_ERROR);
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        }

        String userRequest = chartService.getUserInput(RunningChart , data);
        String fullAns = aiUtil.doChat(userRequest);
        String[] split = fullAns.split(GenChartConstant.AI_CHART_SPILT);

        if (StringUtils.isEmpty(fullAns)) {
            webSocketUtil.sendOneMessage(RunningChart.getUserId().toString() , "出错了，请稍后重试");
            throw new BusinessException(ErrorCode.OPERATION_ERROR, "分析失败");
        }

        //不进行重传，直接失败
        if (split.length < 3) {
            webSocketUtil.sendOneMessage(RunningChart.getUserId().toString(), "系统繁忙");
            //修改生成状态为失败直接确认
            Chart failChart = new Chart();
            failChart.setStatus(GenChartStatusEnum.FAILED.getValue());
            chartService.updateById(failChart);
            //确认消息保证不在重传
            try {
                channel.basicAck(deliveryTag, false);
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
            throw new BusinessException(ErrorCode.OPERATION_ERROR);
        }else {

            work(RunningChart, split[1], split[2], deliveryTag, channel);
        }

        try {
            channel.basicAck(deliveryTag, false);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    public void work(Chart RunningChart , String genChart , String genResult , long deliveryTag , Channel channel){
        //将数据存储到数据库
        Chart finalChart = new Chart();
        if (!StrUtil.isAllNotEmpty(genChart , genResult)){
            throw new BusinessException(ErrorCode.OPERATION_ERROR);
        }
        BeanUtil.copyProperties(RunningChart , finalChart);
        finalChart.setId(RunningChart.getId());
        finalChart.setGenChart(genChart);
        finalChart.setGenResult(genResult);
        finalChart.setStatus(GenChartStatusEnum.SUCCEED.getValue());
        chartService.updateById(finalChart);
        webSocketUtil.sendOneMessage(finalChart.getUserId().toString() , "图表生成好啦，快去看看吧！");

        //更新redis
        Gson gson = new Gson();
        String key = UserConstant.CHART_KEY_PRE + finalChart.getUserId();
        QueryWrapper<Chart> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("userId" , RunningChart.getUserId());
        List<Chart> list = chartService.list(queryWrapper);
        String JsonStr = gson.toJson(list);
        redisTemplate.opsForValue().set(key , JsonStr);


        try {
            channel.basicAck(deliveryTag , false);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }


}
